Hovercraft Path Planning
In this case study, we seek to determine an optimal control policy for the trajectory of a hovercraft that travels to a set of dynamic waypoints while trying to minimize the thrust input.
Formulation
The corresponding dynamic optimization problem is expressed:
\[\begin{aligned} &&\underset{x(t), v(t), u(t)}{\text{min}} &&& \int_{t \in T} |u(t)|_2^2 dt \\ &&\text{s.t.} &&& v(0) = v0\\ &&&&& \frac{dx}{dt} = v(t), && t \in T\\ &&&&& \frac{dv}{dt} = u(t), && t \in T\\ &&&&& x(t_i) = xw_i, && i \in I \end{aligned}\]
where $x(t)$ is the Cartesian position, $v(t)$ is the velocity, $u(t)$ is the thrust input, $xw_i, \ i \in I,$ are the waypoints, and $T$ is the time horizon.
Model Definition
Let's implement this in InfiniteOpt
and first import the packages we need:
using InfiniteOpt, Ipopt
Next we'll specify our waypoint data:
xw = [1 4 6 1; 1 3 0 1] # positions
tw = [0, 25, 50, 60]; # times
We initialize the infinite model and opt to use the Ipopt solver:
m = InfiniteModel(optimizer_with_attributes(Ipopt.Optimizer, "print_level" => 0));
Let's specify our infinite parameter which is time $t \in [0, 60]$:
@infinite_parameter(m, t in [0, 60], num_supports = 61)
t
Now let's specify the decision variables:
@variables(m, begin
# state variables
x[1:2], Infinite(t)
v[1:2], Infinite(t)
# control variables
u[1:2], Infinite(t), (start = 0)
end)
(GeneralVariableRef[x[1](t), x[2](t)], GeneralVariableRef[v[1](t), v[2](t)], GeneralVariableRef[u[1](t), u[2](t)])
Specify the objective:
@objective(m, Min, ∫(u[1]^2 + u[2]^2, t))
∫{t ∈ [0, 60]}[u[1](t)² + u[2](t)²]
Set the initial conditions with respect to the velocity:
@constraint(m, [i = 1:2], v[i](0) == 0)
2-element Vector{InfOptConstraintRef}:
v[1](0) = 0
v[2](0) = 0
Define the point physics ODEs which serve as our system model:
@constraint(m, [i = 1:2], ∂(x[i], t) == v[i])
@constraint(m, [i = 1:2], ∂(v[i], t) == u[i])
2-element Vector{InfOptConstraintRef}:
d/dt[v[1](t)] - u[1](t) = 0, ∀ t ∈ [0, 60]
d/dt[v[2](t)] - u[2](t) = 0, ∀ t ∈ [0, 60]
Ensure we hit all the waypoints:
@constraint(m, [i = 1:2, j = eachindex(tw)], x[i](tw[j]) == xw[i, j])
2×4 Matrix{InfOptConstraintRef}:
x[1](0) = 1 x[1](25) = 4 x[1](50) = 6 x[1](60) = 1
x[2](0) = 1 x[2](25) = 3 x[2](50) = 0 x[2](60) = 1
Problem Solution
Optimize the model:
optimize!(m)
Extract the results:
x_opt = value.(x);
Plot the results:
using Plots
scatter(xw[1,:], xw[2,:], label = "Waypoints", background_color = :transparent)
plot!(x_opt[1], x_opt[2], label = "Trajectory")
xlabel!("x_1")
ylabel!("x_2")
That's it, now we have our optimal trajectory!
Maintenance Tests
These are here to ensure this example stays up to date.
using Test
@test termination_status(m) == MOI.LOCALLY_SOLVED
@test has_values(m)
@test x_opt isa Vector{<:Vector{<:Real}}
Test Passed
This page was generated using Literate.jl.